<?php
namespace Pinenut;

/**
 * Заготовка контейнера для определения конфигурации
 * 
 * Почему не массив, возвращаемый в require? 
 * Потому что обёрнутый в класс массив вернуть в 100 раз быстрей даже закешированного 
 * инклюда.
 * 
 * 
 * TODO: В последствии предполагаю использовать генерацию файлов конфигурации 
 * по аннотациям используя функцию var_export
 * 
 * @author Kosh
 *
 */
abstract class Config {
	
	/**
	 * Конфигурация в виде вложенного массива 
	 * @var array
	 */
	static $config = [];
	
	/**
	 * Массив проинициализированных конфигураций (ключи - имена классов)
	 * @var array
	 */
	static $initialized = [];
	
	
	/**
	 * Строка именем окружения 
	 * Разделенным точнкой для множественных включений
	 * 
	 * @var string
	 */
	static $environment;
	
	static function get($path = null) {
		$class = get_called_class();
		if (!isset(static::$initialized[$class])) {
 			static::$initialized[$class] = true;
			static::initialize();
			static::mergeEnvironment();
		}
		
		if (null !== $path) {
			if (strpos($path, '.') === false) {
				return isset(static::$config[$path])?static::$config[$path]:null;
			}

			$link = &static::$config;
			$parts = explode('.', $path);

			foreach ($parts as $part) {
				if (!isset($link[$part])) {
					return null;
				}
				$link = &$link[$part];
			}

			return $link;
		} else {
			return static::$config;
		}
	}
	
	/**
	 * инициализируем массив конфы, если нужно
	 */
	static function initialize() {}
	
	/**
	 * Добавляем данные других конфигураций в зависимости от окружения
	 */
	protected static function mergeEnvironment() {
		if (!static::$environment) {
			return;
		}
		$baseClass = get_called_class();
		$envs = explode('.', static::$environment);
		foreach ($envs as $env) { 
			$class = preg_replace('#(Config)$#',ucfirst($env).'Config', $baseClass);
			// добавляем имя переменной окружения и проверяем существует 
			// ли конфа с таким именем
			set_error_handler(function() { /* ignore errors */ });
			if (class_exists($class, true)) {
				// мёржим его если найден
				static::$config = 
					array_replace_recursive(static::$config, $class::get());
			}
			restore_error_handler();
		}
	}
	
}